//===----------------------------------------------------------------------===//
//
//                         BusTub
//
// seq_scan_executor.cpp
//
// Identification: src/execution/seq_scan_executor.cpp
//
// Copyright (c) 2015-2021, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "execution/executors/seq_scan_executor.h"

namespace bustub {
/**
 * exec_ctx 是执行操作所需的上下文信息（如事务、缓存等）。
 * plan_ 是一个指向扫描计划节点的指针，定义了扫描的具体内容和过滤条件。
 */
SeqScanExecutor::SeqScanExecutor(ExecutorContext *exec_ctx, const SeqScanPlanNode *plan) : AbstractExecutor(exec_ctx), plan_(plan) {}
/**
 * 首先，通过计划节点 (plan_) 获取要扫描的表的 OID（table_oid_t 类型）。
 * 然后，通过执行上下文获取数据库的目录（Catalog），并使用表的 OID 获取该表的信息（TableInfo）。
 * table_info->table_ 提供了表的实际数据堆（table_heap），table_heap->MakeIterator() 创建了一个表的迭代器。
 * 最后，将该迭代器保存在 table_iter_ 中，以便后续扫描表中的数据。
 */
  void SeqScanExecutor::Init() {
    table_oid_t table_oid = plan_->GetTableOid();
    Catalog *catalog = exec_ctx_->GetCatalog();
    TableInfo *table_info = catalog->GetTable(table_oid);
    auto &table_heap = table_info->table_;
    table_iter_ = std::make_unique<TableIterator>(table_heap->MakeIterator());
  }
  /**
   * Next 方法用于获取下一行符合条件的元组。
   * 方法的参数是一个指向 Tuple 的指针（存储获取到的数据行）和一个指向 RID 的指针（存储数据行的标识符）。
     在 while(true) 循环中，检查迭代器是否已到达表的末尾（table_iter_->IsEnd()），如果是，返回 false，表示扫描完成。
     如果还未结束：
     获取当前行的 RID 和 Tuple 数据，并存储到传入的指针中。
     检查元组是否标记为删除（tuple_meta.is_deleted_），如果标记为删除，跳过该元组。
     如果有过滤条件（filter_predicate_），则对当前元组进行过滤：
     通过 Evaluate 方法对过滤条件进行评估，如果满足条件（返回值为 true），则返回 true，表示找到了一行满足条件的数据。
     如果没有过滤条件，直接返回 true，表示找到了一行数据。
     如果未找到符合条件的元组，继续扫描下一行。
   * @param tuple
   * @param rid
   * @return
   */
  auto SeqScanExecutor::Next(Tuple *tuple, RID *rid) -> bool {
    while(true){
      if(table_iter_->IsEnd()){
        return false;
      }
      *rid = table_iter_->GetRID();
      *tuple = Tuple(table_iter_->GetTuple().second);
      TupleMeta tuple_meta = table_iter_->GetTuple().first;
      ++*table_iter_;
      
      //被标记为被删除的元组就跳过
      if(!tuple_meta.is_deleted_){
        //被标记为要过滤的元组也跳过
        if(plan_->filter_predicate_){
          auto &filter_expr = plan_->filter_predicate_;
          Value value = filter_expr->Evaluate(tuple, plan_->OutputSchema());
          if(!value.IsNull() && value.GetAs<bool>()){
            return true;
          }
        }
        else{
          return true;
        }
      }
    }
  }

}  // namespace bustub
